package cn.edu.scnu.semart.user.service.impl;

import cn.edu.scnu.semart.common.exception.SsyxException;
import cn.edu.scnu.semart.common.result.ResultCodeEnum;
import cn.edu.scnu.semart.common.utils.MD5;
import cn.edu.scnu.semart.model.user.User;
import cn.edu.scnu.semart.user.mapper.UserMapper;
import cn.edu.scnu.semart.user.service.UserService;
import cn.edu.scnu.semart.vo.user.ChangePwdVo;
import cn.edu.scnu.semart.vo.user.UserProfileUpdateVo;
import cn.edu.scnu.semart.vo.user.UserQueryVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

import static cn.edu.scnu.semart.common.result.ResultCodeEnum.PWD_NOTSAME;
import static cn.edu.scnu.semart.common.result.ResultCodeEnum.PWD_ORIERROR;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public IPage<User> selectPage(Page<User> pageParam, UserQueryVo userQueryVo) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

        // 用户ID精确查询
        if (userQueryVo.getUserId() != null) {
            wrapper.eq(User::getUserId, userQueryVo.getUserId());
        }

        // 用户名模糊查询
        if (!StringUtils.isEmpty(userQueryVo.getUsername())) {
            wrapper.like(User::getUsername, userQueryVo.getUsername());
        }

        // 手机号模糊查询
        if (!StringUtils.isEmpty(userQueryVo.getPhone())) {
            wrapper.like(User::getPhone, userQueryVo.getPhone());
        }

        // 邮箱模糊查询
        if (!StringUtils.isEmpty(userQueryVo.getEmail())) {
            wrapper.like(User::getEmail, userQueryVo.getEmail());
        }

        // 用户类型查询（枚举类型）
        if (userQueryVo.getUserType() != null) {
            wrapper.eq(User::getUserType, userQueryVo.getUserType());
        }

        // 用户状态查询（枚举类型）
        if (userQueryVo.getStatus() != null) {
            wrapper.eq(User::getStatus, userQueryVo.getStatus());
        }

        // 默认按创建时间降序排列
        wrapper.orderByDesc(User::getCreatedAt);

        return baseMapper.selectPage(pageParam, wrapper);
    }

    @Override
    public void resetPassword(Integer userId, String newPassword) {
        User user = getById(userId);
        if (user == null) throw new SsyxException(ResultCodeEnum.USER_UNKNOW);
        user.setPassword(MD5.encrypt(newPassword));
        updateById(user);
    }

    @Override
    public void changePassword(Integer currentUserId, ChangePwdVo vo) {
        if (!vo.getNewPassword().equals(vo.getConfirmPassword())) {
            throw new SsyxException(PWD_NOTSAME);
        }
        User user = getById(currentUserId);
        if (!user.getPassword().equals(MD5.encrypt(vo.getOldPassword()))) {
            throw new SsyxException(PWD_ORIERROR);
        }
        user.setPassword(MD5.encrypt(vo.getNewPassword()));
        updateById(user);
    }

    //单次解/禁
    @Override
    public void updateStatus(Long id, User.UserStatus status) {
        lambdaUpdate().set(User::getStatus,status)
                .eq(User::getUserId,id)
                .update();
    }

    /**
     * 批量解/禁
     * @param ids
     * @param status
     */
    @Override
    public void batchUpdateStatus(List<Long> ids, User.UserStatus status) {
        lambdaUpdate()
                .set(User::getStatus,status)
                .in(User::getUserId,ids)
                .update();
    }

    @Override
    public void updateProfile(Integer userId, UserProfileUpdateVo vo) {
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(User::getUserId, userId)
                .set(vo.getUsername() != null, User::getUsername, vo.getUsername())
                .set(vo.getEmail()    != null, User::getEmail,    vo.getEmail())
                .set(vo.getPhone()    != null, User::getPhone,    vo.getPhone())
                .set(User::getUpdatedAt, new Date());
        this.update(wrapper);
    }

    @Override
    public boolean save(User user) {
        // 1. 强制默认值
//        user.setUserType(User.UserType.NORMAL);
//        user.setStatus(User.UserStatus.ACTIVE);

        // 2. 密码加密
        user.setPassword(MD5.encrypt(user.getPassword()));

        // 3. 插入数据库
        return super.save(user);
    }
}